package com.zwz.service.impl;

import com.zwz.entity.*;
import com.zwz.mapper.EnterpriseMapper;
import com.zwz.service.*;

import com.zwz.voObject.DatabaseMetaVO;
import com.zwz.voObject.EnterpriseBean;
import com.zwz.voObject.EnterpriseDetailVO;
import com.zwz.voObject.QueryConditionVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;

@Slf4j
@Service
public class EnterpriseServiceImpl implements EnterpriseService {

    @Autowired
    private EnterpriseMapper enterpriseMapper;
    
    @Autowired
    private InvestmentEmploymentService investmentService;
    
    @Autowired
    private EnterpriseAnnualReportService annualReportService;
    
    @Autowired
    private InformationChangeService changeService;
    
    @Autowired
    private AgentAccountInfoService accountService;
    
    @Autowired
    private OfficialWebsiteInfoService websiteService;
    
    @Autowired
    private CompanyOperationStatusService operationStatusService;
    
    @Autowired
    private QualificationService qualificationService;
    
    @Autowired
    private BusinessAbnormalityService abnormalityService;
    
    @Autowired
    private AdministrativePenaltyService penaltyService;
    
    @Autowired
    private CourtAnnouncementService announcementService;
    
    @Autowired
    private JudgmentDocumentService judgmentService;
    
    @Autowired
    private DishonestPersonService dishonestPersonService;
    
    @Autowired
    private TerminatedCaseService terminatedCaseService;
    
    @Autowired
    private ConsumptionRestrictionService restrictionService;
    
    @Autowired
    private BankruptcyReorganizationService bankruptcyService;
    
    @Autowired
    private TaxpayerQualiService taxpayerQualiService;

    @Autowired
    private DatabaseMetaService databaseMetaService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public EnterpriseInfo getById(Long id) {
        return enterpriseMapper.selectById(id);
    }

    @Override
    @Transactional(readOnly = true)
    public List<EnterpriseInfo> getAll() {
        return enterpriseMapper.selectAll();
    }

    @Override
    @Transactional
    public int create(EnterpriseInfo enterprise) {
        return enterpriseMapper.insert(enterprise);
    }

    @Override
    @Transactional
    public int update(EnterpriseInfo enterprise) {
        return enterpriseMapper.update(enterprise);
    }

    @Override
    @Transactional
    public int delete(Long id) {
        return enterpriseMapper.delete(id);
    }

    @Override
    @Transactional(readOnly = true)
    public EnterpriseDetailVO getEnterpriseDetail(Long id) {
        EnterpriseDetailVO detailVO = new EnterpriseDetailVO();
        
        try {
            // 获取主表信息
            EnterpriseInfo enterprise = getById(id);
            if (enterprise == null) {
                log.error("企业信息不存在: {}", id);
                return null;
            }
            detailVO.setEnterpriseInfo(enterprise);
            
            // 获取投资任职信息
            InvestmentEmploymentInfo investmentInfo = investmentService.getById(Math.toIntExact(id));
            detailVO.setInvestmentEmploymentInfo(investmentInfo);
            
            // 获取年报信息
           EnterpriseAnnualReport  annualReports = annualReportService.getById(Math.toIntExact(id));
            detailVO.setAnnualReports(annualReports);
            
            // 获取变更信息
          InformationChange  changes = changeService.getById(Math.toIntExact(id));
            detailVO.setInformationChanges(changes);
            
            // 获取代理记账信息
            AgentAccountInfo  accountInfos = accountService.getById(Math.toIntExact(id));
            detailVO.setAgentAccountInfos(accountInfos);
            
            // 获取官网信息
           OfficialWebsiteInfo websiteInfos = websiteService.getById(Math.toIntExact(id));
            detailVO.setOfficialWebsiteInfos(websiteInfos);
            
            // 获取经营状态信息
            CompanyOperationStatus  operationStatuses = operationStatusService.getById(Math.toIntExact(id));
            detailVO.setOperationStatuses(operationStatuses);
            
            // 获取资质信息
            QualificationCertificates qualifications = qualificationService.getById(Math.toIntExact(id));
            detailVO.setQualifications(qualifications);
            
            // 获取经营异常信息
           BusinessAbnormality  abnormalities = abnormalityService.getAbnormalityById(Math.toIntExact(id));
            detailVO.setBusinessAbnormalities(abnormalities);

            // todo 获取行政处罚信息.需要增加
//        AdministrativePenalty  penalties = administrativePenaltyService.(id);
//        detailVO.setAdministrativePenalties(penalties);

            //todo 获取行政处罚信息.需要增加 获取法院公告信息
//        CourtAnnouncement announcements = courtAnnouncementService.getById(id);
//        detailVO.setCourtAnnouncements(announcements);

            // 获取裁判文书信息todo 带以后测试
//        JudgmentDocument documents = JudgementService.getById(id);
//        detailVO.setJudgmentDocuments(documents);
//
//        // 获取失信人信息
//        DishonestPerson  dishonestPersons = dishonestPersonService.getById(id);
//        detailVO.setDishonestPersons(dishonestPersons);
//
//        // 获取终本案件信息
//        TerminatedCase terminatedCases = terminatedCaseService.getById(id);
//        detailVO.setTerminatedCases(terminatedCases);
            // 获取限制消费信息
            List<ConsumptionRestriction> restrictions = restrictionService.getByCaseNumber(String.valueOf(id));
            detailVO.setConsumptionRestrictions(restrictions);
            

            
            // 获取纳税人资质信息
            TaxpayerQuali  taxpayerQualis = taxpayerQualiService.getById(Math.toIntExact(id));
            detailVO.setTaxpayerQualis(taxpayerQualis);
        } catch (Exception e) {
            log.error("获取企业详情失败: {}", id, e);
            throw new RuntimeException("获取企业详情失败", e);
        }
        
        return detailVO;
    }

    @Override
    public List<EnterpriseBean> getEnterpriseBean() {
        return null;
    }


    public List<EnterpriseBean> getEnterpriseBean(String companyName) {
        return enterpriseMapper.selectAllBean(companyName);
    }


    /**
     * 根据对应的简介查询对应的主表信息
     *
     * @param CompanyProfile
     * @return
     */
    public List<EnterpriseBean> getEnterpriseBeanByCompanyType(String CompanyProfile) {
        return enterpriseMapper.selectAllBeanByCompanyType(CompanyProfile);
    }


    /**
     * 根据对应的成立时间查询对应的主表信息
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public List<EnterpriseBean> getEnterpriseBeanByDate(String startDate, String endDate) {
        return enterpriseMapper.selectAllBeanByByDate(startDate, endDate);
    }


    /**
     * 根据对应的成立时间查询对应的主表信息
     *
     * @return
     */
    public List<EnterpriseBean> getEnterpriseBeanByStatus(String businessStatus) {
        return enterpriseMapper.selectAllBeanByBusinessStatus(businessStatus);
    }


    @Override
    public PageInfo<EnterpriseBean> getEnterpriseBeanPage(Integer pageNum, Integer pageSize, String companyName) {
        // 开启分页
        PageHelper.startPage(pageNum, pageSize);

        // 查询数据
        List<EnterpriseBean> list = getEnterpriseBean(companyName);

        // 返回分页结果
        return new PageInfo<>(list);
    }

    @Override
    public PageInfo<EnterpriseBean> getEnterpriseBeanPageByCompanyType(Integer pageNum, Integer pageSize, String companyType) {
        // 开启分页
        PageHelper.startPage(pageNum, pageSize);
        // 查询数据
        List<EnterpriseBean> list = getEnterpriseBeanByCompanyType(companyType);
        // 返回分页结果
        return new PageInfo<>(list);
    }

    @Override
    public PageInfo<EnterpriseBean> getEnterpriseBeanPageByDate(Integer pageNum, Integer pageSize, String startDate, String endDate) {
        // 开启分页
        PageHelper.startPage(pageNum, pageSize);
        // 查询数据
        List<EnterpriseBean> list = getEnterpriseBeanByDate(startDate, endDate);
        // 返回分页结果
        return new PageInfo<>(list);
    }


    @Override
    public PageInfo<EnterpriseBean> getEnterpriseBeanPageByStatus(Integer pageNum, Integer pageSize, String businessStatus) {
        // 开启分页
        PageHelper.startPage(pageNum, pageSize);
        // 查询数据
        List<EnterpriseBean> list = getEnterpriseBeanByStatus(businessStatus);
        // 返回分页结果
        return new PageInfo<>(list);
    }


    @Override
    public List<Map<String, Object>> queryByBoolean(QueryConditionVO condition, Integer pageNum, Integer pageSize) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());

        StringBuilder sql = new StringBuilder();
//        sql.append("SELECT * FROM ").append(condition.getTableName())
//           .append(" WHERE ").append(columnName)
        sql.append("SELECT * FROM ").append(condition.getTableName()).append(" ").append("a,enterprise_info b ")
                .append(" where a.enterprise_id=b.id ")
                .append(" and ").append("a.").append(columnName)
                .append(" = ?")
                .append(" LIMIT ?, ?");

        int offset = (pageNum - 1) * pageSize;
        return jdbcTemplate.queryForList(sql.toString(), condition.getValue(), offset, pageSize);
    }

    @Override
    public Long countByBoolean(QueryConditionVO condition) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());

        StringBuilder sql = new StringBuilder();
//        sql.append("SELECT COUNT(*) FROM ").append(condition.getTableName())
//           .append(" WHERE ").append(columnName)
        sql.append("SELECT COUNT(*)  FROM ").append(condition.getTableName()).append(" ").append("a,enterprise_info b ")
                .append(" where a.enterprise_id=b.id ")
                .append(" and ").append("a.").append(columnName)
                .append(" = ?");

        return jdbcTemplate.queryForObject(sql.toString(), Long.class, condition.getValue());
    }

    @Override
    public List<Map<String, Object>> queryByInteger(QueryConditionVO condition, Integer pageNum, Integer pageSize) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());

        StringBuilder sql = new StringBuilder();
//        sql.append("SELECT * FROM ").append(condition.getTableName())
//           .append(" WHERE ").append(columnName).append(" BETWEEN ? AND ?")
//           .append(" LIMIT ?, ?");
        sql.append("SELECT * FROM ").append(condition.getTableName()).append(" ").append("a,enterprise_info b ")
                .append(" where a.enterprise_id=b.id ")
                .append(" and ").append("a.").append(columnName)
                .append(" BETWEEN ? AND ?")
                .append(" LIMIT ?, ?");


        int offset = (pageNum - 1) * pageSize;
        return jdbcTemplate.queryForList(sql.toString(), condition.getMinValue(), condition.getMaxValue(), offset, pageSize);
    }

    @Override
    public Long countByInteger(QueryConditionVO condition) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());

        StringBuilder sql = new StringBuilder();
//        sql.append("SELECT COUNT(*) FROM ").append(condition.getTableName())
//           .append(" WHERE ").append(columnName).append(" BETWEEN ? AND ?");
        sql.append("SELECT COUNT(*)  FROM ").append(condition.getTableName()).append(" ").append("a,enterprise_info b ")
                .append(" where a.enterprise_id=b.id ")
                .append(" and ").append("a.").append(columnName)
                .append(" BETWEEN ? AND ?");


        return jdbcTemplate.queryForObject(sql.toString(), Long.class, condition.getMinValue(), condition.getMaxValue());
    }

    @Override
    public List<Map<String, Object>> queryByFloat(QueryConditionVO condition, Integer pageNum, Integer pageSize) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());
        
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT * FROM ").append(condition.getTableName())
           .append(" WHERE ").append(columnName).append(" BETWEEN ? AND ?")
           .append(" LIMIT ?, ?");
        
        int offset = (pageNum - 1) * pageSize;
        return jdbcTemplate.queryForList(sql.toString(), condition.getMinValue(), condition.getMaxValue(), offset, pageSize);
    }

    @Override
    public Long countByFloat(QueryConditionVO condition) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());
        
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT COUNT(*) FROM ").append(condition.getTableName())
           .append(" WHERE ").append(columnName).append(" BETWEEN ? AND ?");
        
        return jdbcTemplate.queryForObject(sql.toString(), Long.class, condition.getMinValue(), condition.getMaxValue());
    }

    @Override
    public List<Map<String, Object>> queryByString(QueryConditionVO condition, Integer pageNum, Integer pageSize) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());
        
        StringBuilder sql = new StringBuilder();

//        sql.append("SELECT * FROM ").append(condition.getTableName())
//           .append(" WHERE ").append(columnName)
        sql.append("SELECT * FROM ").append(condition.getTableName()).append(" ").append("a,enterprise_info b ")
                .append(" where a.enterprise_id=b.id ")
                .append(" and ").append("a.").append(columnName)

                .append(" LIKE ?")
           .append(" LIMIT ?, ?");
        
        int offset = (pageNum - 1) * pageSize;
        return jdbcTemplate.queryForList(sql.toString(), "%" + condition.getPattern() + "%", offset, pageSize);
    }

    @Override
    public Long countByString(QueryConditionVO condition) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());
        
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT COUNT(*) FROM ").append(condition.getTableName())
           .append(" WHERE ").append(columnName).append(" LIKE ?");
        
        return jdbcTemplate.queryForObject(sql.toString(), Long.class, "%" + condition.getPattern() + "%");
    }

    @Override
    public List<Map<String, Object>> queryByDate(QueryConditionVO condition, Integer pageNum, Integer pageSize) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());

        StringBuilder sql = new StringBuilder();
//        sql.append("SELECT * FROM ").append(condition.getTableName())
//           .append(" WHERE ").append(columnName)
        sql.append("SELECT * FROM ").append(condition.getTableName()).append(" ").append("a,enterprise_info b ")
                .append(" where a.enterprise_id=b.id ")
                .append(" and ").append("a.").append(columnName)
                .append(" BETWEEN ? AND ?")
                .append(" LIMIT ?, ?");

        int offset = (pageNum - 1) * pageSize;
        return jdbcTemplate.queryForList(sql.toString(), condition.getStartDate(), condition.getEndDate(), offset, pageSize);
    }

    @Override
    public Long countByDate(QueryConditionVO condition) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());

        StringBuilder sql = new StringBuilder();
//        sql.append("SELECT COUNT(*) FROM ").append(condition.getTableName())
//           .append(" WHERE ").append(columnName)
        sql.append("SELECT COUNT(*) FROM ").append(condition.getTableName()).append(" ").append("a,enterprise_info b ")
                .append(" where a.enterprise_id=b.id ")
                .append(" and ").append("a.").append(columnName)
                .append(" BETWEEN ? AND ?");

        return jdbcTemplate.queryForObject(sql.toString(), Long.class, condition.getStartDate(), condition.getEndDate());
    }

    @Override
    public List<Map<String, Object>> queryByEnum(QueryConditionVO condition, Integer pageNum, Integer pageSize) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());
        
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT * FROM ").append(condition.getTableName())
           .append(" WHERE ").append(columnName).append(" IN (");
        
        String placeholders = String.join(",", Collections.nCopies(condition.getValues().size(), "?"));
        sql.append(placeholders).append(")")
           .append(" LIMIT ?, ?");
        
        List<Object> params = new ArrayList<>(condition.getValues());
        int offset = (pageNum - 1) * pageSize;
        params.add(offset);
        params.add(pageSize);
        
        return jdbcTemplate.queryForList(sql.toString(), params.toArray());
    }

    @Override
    public Long countByEnum(QueryConditionVO condition) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());
        
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT COUNT(*) FROM ").append(condition.getTableName())
           .append(" WHERE ").append(columnName).append(" IN (");
        
        String placeholders = String.join(",", Collections.nCopies(condition.getValues().size(), "?"));
        sql.append(placeholders).append(")");
        
        return jdbcTemplate.queryForObject(sql.toString(), Long.class, condition.getValues().toArray());
    }

    @Override
    public List<Map<String, Object>> queryGeneral(QueryConditionVO condition, Integer pageNum, Integer pageSize, Integer type) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());

        StringBuilder sql = new StringBuilder();
//        sql.append("SELECT * FROM ").append(condition.getTableName())
//           .append(" WHERE 1=1");
        sql.append("SELECT * FROM ").append(condition.getTableName()).append(" ").append("a,enterprise_info b ")
                .append(" where a.enterprise_id=b.id ");
//                .append(" and ").append("a.").append(columnName);
//                .append(" WHERE 1=1");

        List<Object> params = new ArrayList<>();

        //todo 保留为整型逻辑值
        if (1 == type) {
            if (condition.getValue() != null) {
                sql.append(" AND a.").append(columnName).append(" = ?");
                params.add(condition.getValue());
            }
        } else


            //type=2 默认区间查询
            if (2 == type) {
                if (condition.getMinValue() != null && condition.getMaxValue() != null) {
                    sql.append(" AND a.").append(columnName).append(" BETWEEN ? AND ?");
                    params.add(condition.getMinValue());
                    params.add(condition.getMaxValue());
                }
            } else

                //type=3 默认是字符串查询
                if (3 == type) {
                    if (StringUtils.hasText(condition.getPattern())) {
                        sql.append(" AND a.").append(columnName).append(" LIKE ?");
                        params.add("%" + condition.getPattern() + "%");
                    }
                } else
                    //type=4 默认日期查询
                    if (4 == type
                    ) {
                        if (condition.getStartDate() != null && condition.getEndDate() != null) {
                            sql.append(" AND a.").append(columnName).append(" BETWEEN ? AND ?");
                            params.add(condition.getStartDate());
                            params.add(condition.getEndDate());
                        }
                    } else

                        //todo 保留
//        if (condition.getValues() != null && !condition.getValues().isEmpty()) {
//            sql.append(" AND ").append(columnName).append(" IN (");
//            String placeholders = String.join(",", Collections.nCopies(condition.getValues().size(), "?"));
//            sql.append(placeholders).append(")");
//            params.addAll(condition.getValues());
//        }

                        //type=5 默认是逻辑值查询
                        if (5 == type) {
                            if (Boolean.TRUE.equals(condition.getIsNull())) {
                                sql.append(" AND a.").append(columnName).append(" IS NULL");
                            }

                            if (Boolean.TRUE.equals(condition.getIsNotNull())) {
                                sql.append(" AND a.").append(columnName).append(" IS NOT NULL");
                            }
                        }


        sql.append(" LIMIT ?, ?");
        int offset = (pageNum - 1) * pageSize;
        params.add(offset);
        params.add(pageSize);

        log.info(">>>>>>>查询SQL：" + sql.toString());
        return jdbcTemplate.queryForList(sql.toString(), params.toArray());
    }

    /**
     * 需要考虑业务去重,
     *
     * @param condition
     * @param type
     * @return
     */
    @Override
    public Long countGeneral(QueryConditionVO condition, Integer type) {
        DatabaseMetaVO.TableInfo tableInfo = databaseMetaService.getTableInfo(condition.getTableName());
        String columnName = getColumnName(tableInfo, condition.getFieldName());

        StringBuilder sql = new StringBuilder();

        sql.append("SELECT COUNT(DISTINCT b.id) FROM ")
                .append(condition.getTableName()).append(" a ")
                .append("JOIN enterprise_info b ON a.enterprise_id = b.id ")
                .append(" WHERE 1=1");

        List<Object> params = new ArrayList<>();

        //todo 保留整型逻辑值的查询
        if (1 == type) {
            if (condition.getValue() != null) {
                sql.append(" AND a.").append(columnName).append(" = ?");
                params.add(condition.getValue());
            }
        } else if (2 == type) {
            if (condition.getMinValue() != null && condition.getMaxValue() != null) {
                sql.append(" AND a.").append(columnName).append(" BETWEEN ? AND ?");
                params.add(condition.getMinValue());
                params.add(condition.getMaxValue());
            }
        } else if (3 == type) {
            if (StringUtils.hasText(condition.getPattern())) {
                sql.append(" AND a.").append(columnName).append(" LIKE ?");
                params.add("%" + condition.getPattern() + "%");
            }
        } else if (4 == type) {
            if (condition.getStartDate() != null && condition.getEndDate() != null) {
                sql.append(" AND a.").append(columnName).append(" BETWEEN ? AND ?");
                params.add(condition.getStartDate());
                params.add(condition.getEndDate());
            }
        } else


//        if (condition.getValues() != null && !condition.getValues().isEmpty()) {
//            sql.append(" AND ").append(columnName).append(" IN (");
//            String placeholders = String.join(",", Collections.nCopies(condition.getValues().size(), "?"));
//            sql.append(placeholders).append(")");
//            params.addAll(condition.getValues());
//        }

            if (5 == type) {
                if (Boolean.TRUE.equals(condition.getIsNull())) {
                    sql.append(" AND a.").append(columnName).append(" IS NULL");
                }

                if (Boolean.TRUE.equals(condition.getIsNotNull())) {
                    sql.append(" AND a.").append(columnName).append(" IS NOT NULL");
                }
            }

        log.info(">>>>>>>统计SQL：" + sql.toString());

        return jdbcTemplate.queryForObject(sql.toString(), Long.class, params.toArray());
    }

    /**
     * 根据驼峰命名的字段名获取数据库列名
     */
    private String getColumnName(DatabaseMetaVO.TableInfo tableInfo, String fieldName) {
        return tableInfo.getColumns().stream()
                .filter(column -> column.getColumnName().equalsIgnoreCase(fieldName))
                .findFirst()
                .map(column -> column.getColumnName())
                .orElseThrow(() -> new IllegalArgumentException("Field not found: " + fieldName));
    }
}